#pragma once

#include <windows.h>
#include <d3dx9.h>
#include "dinput.h"
#include "assert.h"
#include <string>
#include "SimpleRender.h"




#define DIRECTINPUT_VERSION 0x0800

#define INPUT_MAX_CONTROLLERS	(16)

class Input
{
public:

	static Input& Get();
	static void Kill();

	bool Init();
	void Process();

	typedef enum KeyState
	{
		KeyState_NotPressed=0,
		KeyState_Pressed,
		KeyState_Held,
		KeyState_Released,
		KeyState_MaxKeyStates
	}KeyState;

	class InputDevice
	{
	public:

		InputDevice();
		~InputDevice();


		virtual bool Init() = 0;

		virtual void Process (void) = 0;
		virtual void Shutdown(void);


		bool Process(void *pData, int DataSize);


		KeyState GetKey(int KeyID) const;


		int GetKeyCount()	const;


	protected:

		void AllocateKeys(int NoOfKeys);

		void UpdateKey(bool bPressed, KeyState *pKey);


		LPDIRECTINPUTDEVICE8	DeviceHandle; 

		int			KeyCount;
		KeyState	*pProcessedKeys;		

	};

	class Mouse : public InputDevice
	{
	public:

		Mouse();
		bool Init();
		void Process (void);

		const D3DXVECTOR2 &GetPosition(void) const;		
		const D3DXVECTOR2 &GetOldPosition(void) const;

		typedef enum Key{Key_Left = 0
			,Key_Middle = 2
			,Key_Right = 1
		};

	private:

		D3DXVECTOR2 mPosition;
		D3DXVECTOR2 mOldPosition;
	};

	class Keyboard : public InputDevice
	{
	public:

		Keyboard();
		bool Init();
		void Process (void);
	};

	class Controller : public InputDevice
	{
	public:

		Controller();
		bool Init(void);
		bool Init(LPCDIDEVICEINSTANCE pData);
		void Process (void);

		bool bInUse;

		D3DXVECTOR2 analog[3];

		std::string mName;

	};


	const Mouse &GetMouse() ;
	const Keyboard &GetKeyboard();

	const Controller& GetController(unsigned int Index);

	LPDIRECTINPUT8	GetDInput()
	{
		return 	mDirectInput; 
	}




private:

	Input();
	~Input();

	LPDIRECTINPUT8	mDirectInput; 

	Mouse			mMouse;
	Keyboard		mKeyboard;

	Controller		mController[INPUT_MAX_CONTROLLERS];

	static Input*   mInput;

	static BOOL CALLBACK mAddJoystick( LPCDIDEVICEINSTANCE pInst,VOID* pvContext );



};
